/**
 * Copyright c FOUNDER 2005 All Rights Reserved.
 * ListDataSet.java
 */
package com.iori.common.db.dbctrl;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;




/**
 * [クラス名]<br>
 *  リストデータセット<br><br>
 * [機能概要]<br>
 *  DataAccessorのexecuteQueryAsListメソッドによって取得した結果への
 *  順次アクセスを容易にするためのユーティリティクラス。<br><br>
 * [変更履歴]<br>
 *  2005/01/07 ver1.00 新規作成 zhanjc<br>
 *
 * @see jp.co.pia.bety.front.common.db.dbctrl.DataAccessor#executeQueryAsList()
 * @see jp.co.pia.bety.front.common.db.dbctrl.DataSet
 *
 * @author zhanjc
 * @version 1.00
 */
public class ListDataSet implements DataSet {

	protected static Log logger = LogFactory.getLog(ListDataSet.class);

	/**
	 * DataAccessor.executeQueryの結果List
	 */
	private List dataList = null;

	/**
	 * 現在アクセス中のリストのインテックス
	 */
	private int currentIndex = -1;

	/**
	 *
	 */
	private DataSetMetaData metaData = null;

	/**
	 * 順次アクセスを行うListの初期化を行う。
	 *
	 * @param list DataAccessor.executeQueryAsListの結果
	 */
	public ListDataSet(List list) {
		this.dataList = list;
	}

	/**
	 * 順次アクセスを行うListの初期化を行う。
	 *
	 * @param valuelist
	 * @param nameList
	 */
	public ListDataSet(List valuelist, List nameList) {
		this.dataList = valuelist;
		this.metaData = new DataSetMetaDataImpl(nameList);
	}

	/**
	 * レコード件数を取得する。
	 *
	 * @return レコード件数
	 */
	public int getCount() {
		if (this.dataList == null)
			return 0;
		return this.dataList.size();
	}

	/**
	 * カレントレコードを次のレコードに移動する。<br>
	 * カレントレコードがレコードの末端を超えるとfalseを返す。
	 *
	 * @return カレントレコードがレコードの末端に達していなければtrue
	 */
	public boolean next() {
		if (this.dataList == null)
			return false;
		this.currentIndex++;
		if (this.currentIndex < this.getCount()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * カレントレコードを初期化し、レコードを先頭から再取得できるようになる。<br>
	 * 実際にレコードを再取得する場合には、このメソッド呼出し後に再びnextメソッドを
	 * 呼び出さなければならない。
	 */
	public void reset() {
		this.currentIndex = -1;
	}

	/**
	 * カレントレコードの指定したカラムの値をObjectとして取得する。
	 *
	 * @param name カラム名
	 *
	 * @return カレントレコードのカラム値
	 */
	public Object getObject(String name) {
		if ((this.currentIndex > -1)
			&& (this.currentIndex < this.getCount())) {
			Map record = (Map) this.dataList.get(this.currentIndex);
			return record.get(name.toUpperCase());
		}
		return null;
	}

	/**
	 * カレントレコードの指定したカラム名からカラム値のJavaデータ型を取得する。
	 *
	 * @param name カラム名
	 *
	 * @return カレントレコードのカラム値のJavaデータ型
	 */
	public String getType(String name) {
		Object obj = this.getObject(name);
		if (obj != null) {
			return this.getObject(name).getClass().getName();
		} else {
			return null;
		}
	}

	/**
	 * カレントレコードの指定したカラムの値をStringとして取得する。
	 *
	 * @param name カラム名
	 *
	 * @return カレントレコードのカラム値
	 */
	public String getString(String name) {
		Object obj = this.getObject(name);
		if (obj instanceof String) {
			return (String) obj;
		} else {
			if (obj != null) {
				return obj.toString();
			} else {
				return null;
			}
		}
	}

	/**
	 * カレントレコードの指定したカラムの値をIntegerとして取得する。<br>
	 * int値に変換できない場合はnullを返す。
	 *
	 * @param name カラム名
	 *
	 * @return カレントレコードのカラム値
	 */
	public Integer getInteger(String name) {
		try {
			Object obj = this.getObject(name);
			if (obj instanceof Integer) {
				return (Integer) obj;
			} else {
				if (obj != null) {
					return new Integer(obj.toString());
				} else {
					return null;
				}
			}
		} catch (NumberFormatException ne) {
			return null;
		}
	}

	/**
	 * カレントレコードの指定したカラムの値をLongとして取得する。<br>
	 * long値に変換できない場合はnullを返す。
	 *
	 * @param name カラム名
	 *
	 * @return カレントレコードのカラム値
	 */
	public Long getLong(String name) {
		try {
			Object obj = this.getObject(name);
			if (obj instanceof Long) {
				return (Long) obj;
			} else {
				if (obj != null) {
					return new Long(obj.toString());
				} else {
					return null;
				}
			}
		} catch (NumberFormatException ne) {
			return null;
		}
	}

	/**
	 * カレントレコードの指定したカラムの値をFloatとして取得する。<br>
	 * float値に変換できない場合はnullを返す。
	 *
	 * @param name カラム名
	 *
	 * @return カレントレコードのカラム値
	 */
	public Float getFloat(String name) {
		try {
			Object obj = this.getObject(name);
			if (obj instanceof Float) {
				return (Float) obj;
			} else {
				if (obj != null) {
					return new Float(obj.toString());
				} else {
					return null;
				}
			}
		} catch (NumberFormatException ne) {
			return null;
		}
	}

	/**
	 * カレントレコードの指定したカラムの値をDoubleとして取得する。<br>
	 * double値に変換できない場合はnullを返す。
	 *
	 * @param name カラム名
	 *
	 * @return カレントレコードのカラム値
	 */
	public Double getDouble(String name) {
		try {
			Object obj = this.getObject(name);
			if (obj instanceof Double) {
				return (Double) obj;
			} else {
				if (obj != null) {
					return new Double(obj.toString());
				} else {
					return null;
				}
			}
		} catch (NumberFormatException ne) {
			return null;
		}
	}

	/**
	 * カレントレコードの指定したカラムの値をBooleanとして取得する。<br>
	 * boolean値に変換できない場合はfalseとして扱う。
	 *
	 * @param name カラム名
	 *
	 * @return カレントレコードのカラム値
	 */
	public Boolean getBoolean(String name) {
		Object obj = this.getObject(name);
		if (obj instanceof Boolean) {
			return (Boolean) obj;
		} else {
			if (obj != null) {
				String value = obj.toString();
				if ((value == null) || (value.trim().equals(""))) {
					return null;
				} else {
					return new Boolean(value);
				}
			} else {
				return null;
			}
		}
	}

	/**
	 * Retrieves the  number, types and properties of
	 * this <code>DataSet</code> object's columns.
	 *
	 * @return the description of this <code>DataSet</code> object's columns
	 * @exception SQLException if a database access error occurs
	 */
	public DataSetMetaData getMetaData() {
		if (metaData == null) {
			logger.error("metaData == null");
		}
		return metaData;
	}
}
